package cc.vv.party.service.impl;

import cc.vv.party.beans.model.Role;
import cc.vv.party.beans.model.RolePermission
import cc.vv.party.beans.model.UserRole
import cc.vv.party.beans.vo.OrgVO
import cc.vv.party.beans.vo.PermissionVO
import cc.vv.party.beans.vo.RoleVO
import cc.vv.party.mapper.RoleMapper;
import cc.vv.party.service.RoleService;
import cc.vv.party.common.base.BaseServiceImpl;
import cc.vv.party.common.constants.StatusCode
import cc.vv.party.common.ext.uuid
import cc.vv.party.exception.BizException
import cc.vv.party.param.RoleParam
import cc.vv.party.service.PermissionService
import cc.vv.party.service.RolePermissionService
import cc.vv.party.service.UserRoleService
import com.baomidou.mybatisplus.mapper.EntityWrapper
import commonx.core.content.transfer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author Gyb
 * @since 2018-10-13
 */
@Service
open class RoleServiceImpl : BaseServiceImpl<RoleMapper, Role>(), RoleService {

    @Autowired
    lateinit var rolePermissionService: RolePermissionService

    @Autowired
    lateinit var userRoleService: UserRoleService

    @Autowired
    lateinit var permissionService: PermissionService

    @Transactional
    override fun addRole(param: RoleParam, currentUser: String) {
        val existsRole = selectOne(EntityWrapper<Role>().ge("type", param.roleType))
        if (existsRole != null) {
            throw BizException(StatusCode.ERROR.statusCode, "${param.roleType.toString()}类型的角色已经存在,不能重复添加")
        }
        val role = param.transfer<Role>()
        role.createUser = currentUser
        role.id = uuid()

        val rolePermissionList = mutableListOf<RolePermission>()
        for (pid in param.permissionList!!) {
            val rp = RolePermission()
            rp.permissionId = pid
            rp.roleId = role.id
            rp.createUser = currentUser
            rolePermissionList.add(rp)
        }

        insert(role)
        rolePermissionService.insertBatch(rolePermissionList)
    }

    @Transactional
    override fun deleteRole(id: String) {
        rolePermissionService.delete(EntityWrapper<RolePermission>().ge("role_id", id))
        userRoleService.delete(EntityWrapper<UserRole>().ge("role_id", id))
        deleteById(id)
    }

    override fun detail(id: String): RoleVO {
        val role = selectById(id) ?: throw BizException(StatusCode.FIELD_VALUE_ERROR.statusCode, "角色不存在")
        val permissionList = permissionService.getPermissionListByRoleId(id)
        val map = permissionList.associateBy { it.id!! }
        val allChildrenList = permissionList.filter { it.parentId != "00" }.toList()
        val rootMap = map.filter { it.value.parentId == "00" }
        for (node in allChildrenList) {
            val rootNode = rootMap[node.parentId]
            if (rootNode != null) {
                if (rootNode.children == null) {
                    rootNode.children = mutableListOf()
                }
                rootNode.children!!.add(node)
            } else {
                val parent = map[node.parentId] ?: continue
                if (parent.children == null) {
                    parent.children = mutableListOf()
                }
                parent.children!!.add(node)
            }
        }
        val roleVO = role.transfer<RoleVO>()
        roleVO.permissionList = rootMap.values.toList()
        return roleVO
    }

    @Transactional
    override fun updateRole(id: String, param: RoleParam, currentUser: String) {
        val role = selectById(id) ?: throw BizException(StatusCode.FIELD_VALUE_ERROR.statusCode, "角色不存在")
        if (param.roleName.isNullOrEmpty()) {
            role.name = param.roleName
        }
        if (param.description.isNullOrEmpty()) {
            role.description = param.description
        }
        if (param.roleType != null) {
            role.type = param.roleType
        }

        val rolePermissionList = mutableListOf<RolePermission>()
        for (pid in param.permissionList!!) {
            val rp = RolePermission()
            rp.permissionId = pid
            rp.roleId = role.id
            rp.createUser = currentUser
            rolePermissionList.add(rp)
        }
        updateById(role)
        rolePermissionService.delete(
            EntityWrapper<RolePermission>().eq
                ("role_id", role.id)
        )
        rolePermissionService.insertBatch(rolePermissionList)
    }
}
